package cdu.sl.service.impl;

import cdu.sl.common.utils.BaseContext;
import cdu.sl.domain.dto.FolderCreateDTO;
import cdu.sl.domain.dto.FolderUpdateDTO;
import cdu.sl.domain.po.Folder;
import cdu.sl.domain.po.FolderStudySet;
import cdu.sl.domain.po.StudySet;
import cdu.sl.domain.vo.FolderVO;
import cdu.sl.exception.BusinessException;
import cdu.sl.mapper.FolderMapper;
import cdu.sl.mapper.FolderStudySetMapper;
import cdu.sl.mapper.StudySetMapper;
import cdu.sl.service.FolderService;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
@Slf4j
public class FolderServiceImpl extends ServiceImpl<FolderMapper, Folder> implements FolderService {

    private final FolderMapper folderMapper;

    private final FolderStudySetMapper folderStudySetMapper;

    private final StudySetMapper studySetMapper;

    /**
     * 创建文件夹
     *
     * @param folderCreateDTO 创建文件夹数据传输对象
     */
    @Override
    public void createFolder(FolderCreateDTO folderCreateDTO) {
        Long userId = BaseContext.getCurrentId();
        // 1.先查一下用户已有的文件夹
        List<Folder> usersFolders = lambdaQuery().eq(Folder::getUserId, userId).list();

        // 2.检查当前要创建的文件夹是否重复
        usersFolders.forEach(folder -> {
            if (folder.getName().equals(folderCreateDTO.getName()))
                throw new BusinessException("文件夹已存在！");
        });

        Folder folder = new Folder();
        BeanUtil.copyProperties(folderCreateDTO, folder);
        folder.setUserId(userId);
        // 3.文件夹没有重复 , 直接插入即可
        folderMapper.insert(folder);
    }


    /**
     * 获取当前用户的文件夹列表
     *
     * @return
     */
    @Override
    public List<FolderVO> getCurrentUserFolder() {
        // 1.获取用户id
        Long userId = BaseContext.getCurrentId();

        // 2.查询文件夹列表
        List<Folder> folderList = lambdaQuery().eq(Folder::getUserId, userId).list();
        // 获取到VO集合
        List<FolderVO> folderVOList = BeanUtil.copyToList(folderList, FolderVO.class);

        // 从tb_folder_study_sets中获取文件夹中的学习集
        folderVOList = folderVOList.stream().map(folderVO -> {
            // 根据文件夹id查询到此文件夹下的学习集
            // 构建查询条件
            QueryWrapper<FolderStudySet> queryWrapper = new QueryWrapper<FolderStudySet>()
                    .eq("folder_id", folderVO.getId());

            // 查找文件夹与学习集关联表
            List<FolderStudySet> folderStudySetList = folderStudySetMapper.selectList(queryWrapper);

            // 查找学习集
            List<StudySet> studySetList = folderStudySetList.stream()
                    .map(folderStudySet -> studySetMapper.selectById(folderStudySet.getStudySetId()))
                    .collect(Collectors.toList());

            // 将学习集基本信息存入folderVO
            folderVO.setStudySetList(studySetList);
            return folderVO;
        }).collect(Collectors.toList());

        return folderVOList;
    }

    /**
     * 更新文件夹内容
     *
     * @param folderUpdateDTO 更新文件夹数据传输对象
     */
    @Override
    @Transactional
    public void updateFolder(FolderUpdateDTO folderUpdateDTO) {
        // 1.检查id合法性
        Folder folder = folderMapper.selectById(folderUpdateDTO.getId());
        Assert.notNull(folder, "文件夹不存在！");

        // 2.构建更新条件
        UpdateWrapper<Folder> updateWrapper = new UpdateWrapper<Folder>()
                .eq("id", folderUpdateDTO.getId())
                .set("name", folderUpdateDTO.getName())
                .set("study_set_count", folderUpdateDTO.getStudySetManageDTOList().size());


        folderMapper.update(folder, updateWrapper);

        // 向tb_folder_study_sets中插入数据
        if (folderUpdateDTO.getStudySetManageDTOList().isEmpty()) {
            QueryWrapper<FolderStudySet> queryWrapper = new QueryWrapper<FolderStudySet>()
                    .eq("folder_id", folderUpdateDTO.getId());
            folderStudySetMapper.delete(queryWrapper);
            return;
        }

        // 如果用户修改文件夹中的学习集数据 , 可能是删除或者新增
        // 这里还是先删除有关的学习集数据 , 再新增
        QueryWrapper<FolderStudySet> queryWrapper = new QueryWrapper<FolderStudySet>()
                .eq("folder_id", folderUpdateDTO.getId());
        folderStudySetMapper.delete(queryWrapper);

        // 插入文件夹中的学习集数据
        folderUpdateDTO.getStudySetManageDTOList().forEach(studySetManageDTO -> {
            FolderStudySet folderStudySet = new FolderStudySet();
            folderStudySet.setFolderId(folderUpdateDTO.getId());
            folderStudySet.setStudySetId(studySetManageDTO.getId());
            folderStudySet.setCreatedAt(LocalDateTime.now());
            folderStudySetMapper.insert(folderStudySet);
        });
    }


    /**
     * 根据id获取文件夹详情
     *
     * @param id 文件夹id
     * @return 文件夹视图模型对象
     */
    @Override
    public FolderVO getFolderById(Long id) {
        // 1.根据id查询基本信息
        Folder folder = lambdaQuery().eq(Folder::getId, id).one();
        Assert.notNull(folder, "文件夹不存在！");

        // 2.构建返回结果
        FolderVO folderVO = new FolderVO();
        BeanUtil.copyProperties(folder,folderVO);

        // 根据文件夹id查询到FolderStudySet记录列表
        QueryWrapper<FolderStudySet> queryWrapper = new QueryWrapper<FolderStudySet>()
                .eq("folder_id", id);
        List<FolderStudySet> folderStudySetList = folderStudySetMapper.selectList(queryWrapper);

        // 根据此记录查询学习集数据
        List<StudySet> studySetList = folderStudySetList.stream().map(folderStudySet ->
                        studySetMapper.selectById(folderStudySet.getStudySetId()))
                .collect(Collectors.toList());

        folderVO.setStudySetList(studySetList);
        return folderVO;
    }


    /**
     * 根据id删除文件夹
     * @param id 文件夹id
     */
    @Override
    @Transactional
    public void deleteFolder(Long id) {
       // 1.删除文件夹
        QueryWrapper<Folder> queryWrapper=new QueryWrapper<Folder>().eq("id",id);
        remove(queryWrapper);

        // 2.删除文件夹与学习集的关联表数据
        QueryWrapper<FolderStudySet> folderStudySetQueryWrapper=new QueryWrapper<FolderStudySet>().eq("folder_id",id);
        folderStudySetMapper.delete(folderStudySetQueryWrapper);
        log.info("已删除与：{}有关的的文件夹及关联关系",id);
    }



}
